package imgshare.common.sse;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class SseEmitters {

    private static final Log log = LogFactory.get();

    private final Map<Integer, SseEmitter> emitterMap = new ConcurrentHashMap<>();

    public SseEmitter connect(Integer id) {

        SseEmitter previousEmitter = this.emitterMap.get(id);
        if (previousEmitter != null) {
            log.warn("用户[{}]重用了之前的emitter",id);
            return previousEmitter;
        }
        SseEmitter emitter = new SseEmitter(3600000L);
        emitter.onCompletion(() -> {
            log.info("Emitter completed, key is: {}",id);
            remove(id);
        });
        emitter.onTimeout(() -> {
            log.warn("Emitter timeout, key is: {}",id);
        });
        emitter.onError((throwable) -> {
            log.warn("连接异常: {}", id);
        });
        this.emitterMap.put(id,emitter);
        log.info("创建了新的emitter，对应key为：{}",id);
        return emitter;
    }

    /**
     * 给指定用户发送消息
     * @param userId
     * @param object
     */
    public void sendMessage(Integer userId, Object object) {
        if (emitterMap.containsKey(userId)) {
            try {
                emitterMap.get(userId).send(object, MediaType.APPLICATION_JSON);
            } catch (IOException e) {
                log.error("用户[{}]推送异常:{}",userId,e.getMessage());
            }
        }
    }

    /**
     * 群发消息给指定用户群
     */
    public void batchSendMessage(Object object, List<Integer> ids) {
        ids.forEach(userId -> sendMessage(userId, object));
    }

    /**
     * 群发所有人
     */
    public void batchSendMessage(Object object) {
        emitterMap.forEach((k, v) -> {
            try {
                log.info("send to user:{}", k);
                v.send(object, MediaType.APPLICATION_JSON);
            } catch (IOException e) {
                log.error("用户[{}]推送异常:{}", k, e.getMessage());
            }
        });
    }

    public SseEmitter get(Integer id) {
        return this.emitterMap.get(id);
    }

    public void remove(Integer id) {
        this.emitterMap.remove(id);
        log.info("移除用户: {}",id);
    }

    // 获取当前连接数
    public int count() {
        return this.emitterMap.size();
    }


}
